/**
 * 战斗引擎 - 负责整个战斗流程的控制
 * 采用清晰的状态管理和事件驱动架构
 */

import { IBattleEngine, IBattleParticipant, IBattleAction, IBattleActionResult, IBattleResult, IBattleLogEntry, BattleState } from '../architecture/interfaces';
import { IEventManager, IEvent } from '../architecture/interfaces';
import BattleLogger from '../BattleLogger';

/**
 * 战斗引擎实现
 */
export class BattleEngine implements IBattleEngine {
    /** 当前战斗状态 */
    public state: BattleState = BattleState.PREPARING;
    
    /** 参与者列表 */
    public participants: IBattleParticipant[] = [];
    
    /** 当前回合 */
    public currentRound: number = 0;
    
    /** 最大回合数 */
    public maxRounds: number = 50;
    
    /** 战斗日志 */
    private battleLog: IBattleLogEntry[] = [];
    
    /** 事件管理器 */
    private eventManager: IEventManager;
    
    /** 战斗开始时间 */
    private startTime: number = 0;
    
    /** 战斗结束时间 */
    private endTime: number = 0;

    constructor(eventManager: IEventManager) {
        this.eventManager = eventManager;
    }

    /**
     * 初始化战斗
     * @param participants 参与者列表
     */
    public initialize(participants: IBattleParticipant[]): void {
        this.participants = participants;
        this.currentRound = 0;
        this.battleLog = [];
        this.state = BattleState.PREPARING;
        
        // 验证参与者
        if (participants.length < 2) {
            throw new Error('战斗至少需要2个参与者');
        }
        
        // 检查是否有存活者
        const aliveParticipants = participants.filter(p => p.isAlive());
        if (aliveParticipants.length < 2) {
            throw new Error('战斗至少需要2个存活者');
        }
        
        BattleLogger.log('info', '战斗初始化完成', {
            participantCount: participants.length,
            aliveCount: aliveParticipants.length
        });
    }

    /**
     * 开始战斗
     */
    public start(): void {
        if (this.state !== BattleState.PREPARING) {
            throw new Error('战斗状态错误，无法开始');
        }
        
        this.state = BattleState.IN_PROGRESS;
        this.startTime = Date.now();
        this.currentRound = 1;
        
        // 触发战斗开始事件
        this.eventManager.emit({
            type: 'battle_start',
            data: { participants: this.participants },
            timestamp: Date.now()
        });
        
        BattleLogger.log('info', '战斗开始', {
            round: this.currentRound,
            participantCount: this.participants.length
        });
    }

    /**
     * 执行回合
     */
    public executeRound(): void {
        if (this.state !== BattleState.IN_PROGRESS) {
            throw new Error('战斗未进行中，无法执行回合');
        }
        
        if (this.isBattleOver()) {
            this.end();
            return;
        }
        
        // 获取存活者
        const aliveParticipants = this.participants.filter(p => p.isAlive());
        const homeTeam = aliveParticipants.filter(p => p.team === 'home');
        const awayTeam = aliveParticipants.filter(p => p.team === 'away');
        
        // 检查是否有一方全部死亡
        if (homeTeam.length === 0 || awayTeam.length === 0) {
            this.end();
            return;
        }
        
        // 执行主场行动
        for (const participant of homeTeam) {
            if (participant.isAlive()) {
                this.executeParticipantAction(participant, awayTeam);
            }
        }
        
        // 检查客场是否还有存活者
        const remainingAwayTeam = awayTeam.filter(p => p.isAlive());
        if (remainingAwayTeam.length === 0) {
            this.end();
            return;
        }
        
        // 执行客场行动
        for (const participant of remainingAwayTeam) {
            if (participant.isAlive()) {
                this.executeParticipantAction(participant, homeTeam);
            }
        }
        
        // 回合结束处理
        this.endRound();
        
        this.currentRound++;
        
        // 检查最大回合数
        if (this.currentRound > this.maxRounds) {
            this.end();
        }
    }

    /**
     * 执行参与者行动
     * @param participant 参与者
     * @param opponents 对手列表
     */
    private executeParticipantAction(participant: IBattleParticipant, opponents: IBattleParticipant[]): void {
        if (!participant.isAlive() || opponents.length === 0) {
            return;
        }
        
        // 选择目标
        const target = participant.selectTarget(opponents);
        if (!target || !target.isAlive()) {
            return;
        }
        
        // 执行行动
        const action = participant.performAction([target]);
        if (!action) {
            return;
        }
        
        // 执行行动
        const result = action.execute();
        
        // 记录战斗日志
        this.addBattleLog({
            round: this.currentRound,
            actorId: participant.id,
            targetId: target.id,
            actionType: action.type,
            description: result.log,
            valueChange: result.damage + result.healing,
            timestamp: Date.now()
        });
        
        // 触发行动事件
        this.eventManager.emit({
            type: 'battle_action',
            data: { action, result },
            timestamp: Date.now()
        });
        
        // 检查目标是否死亡
        if (!target.isAlive()) {
            this.eventManager.emit({
                type: 'battle_kill',
                data: { killer: participant, victim: target },
                timestamp: Date.now()
            });
        }
    }

    /**
     * 回合结束处理
     */
    private endRound(): void {
        // 更新所有参与者的效果
        for (const participant of this.participants) {
            if (participant.isAlive()) {
                // 这里可以添加效果更新逻辑
            }
        }
        
        // 触发回合结束事件
        this.eventManager.emit({
            type: 'battle_round_end',
            data: { round: this.currentRound },
            timestamp: Date.now()
        });
    }

    /**
     * 结束战斗
     */
    public end(): IBattleResult {
        this.state = BattleState.FINISHED;
        this.endTime = Date.now();
        
        const winner = this.getWinner();
        const result: IBattleResult = {
            winner: winner || 'draw',
            rounds: this.currentRound,
            participantStates: new Map(),
            battleLog: this.battleLog,
            rewards: []
        };
        
        // 记录参与者最终状态
        for (const participant of this.participants) {
            result.participantStates.set(participant.id, participant);
        }
        
        // 触发战斗结束事件
        this.eventManager.emit({
            type: 'battle_end',
            data: { result },
            timestamp: Date.now()
        });
        
        BattleLogger.log('info', '战斗结束', {
            winner,
            rounds: this.currentRound,
            duration: this.endTime - this.startTime
        });
        
        return result;
    }

    /**
     * 检查战斗是否结束
     */
    public isBattleOver(): boolean {
        if (this.state !== BattleState.IN_PROGRESS) {
            return true;
        }
        
        const aliveParticipants = this.participants.filter(p => p.isAlive());
        const homeTeam = aliveParticipants.filter(p => p.team === 'home');
        const awayTeam = aliveParticipants.filter(p => p.team === 'away');
        
        return homeTeam.length === 0 || awayTeam.length === 0 || this.currentRound > this.maxRounds;
    }

    /**
     * 获取获胜方
     */
    public getWinner(): 'home' | 'away' | null {
        if (this.state !== BattleState.FINISHED) {
            return null;
        }
        
        const aliveParticipants = this.participants.filter(p => p.isAlive());
        const homeTeam = aliveParticipants.filter(p => p.team === 'home');
        const awayTeam = aliveParticipants.filter(p => p.team === 'away');
        
        if (homeTeam.length > 0 && awayTeam.length === 0) {
            return 'home';
        } else if (awayTeam.length > 0 && homeTeam.length === 0) {
            return 'away';
        } else if (this.currentRound > this.maxRounds) {
            // 回合数超限，根据存活人数判断
            if (homeTeam.length > awayTeam.length) {
                return 'home';
            } else if (awayTeam.length > homeTeam.length) {
                return 'away';
            } else {
                return null; // 平局
            }
        }
        
        return null;
    }

    /**
     * 添加战斗日志
     * @param logEntry 日志条目
     */
    private addBattleLog(logEntry: IBattleLogEntry): void {
        this.battleLog.push(logEntry);
        
        // 限制日志数量，避免内存泄漏
        if (this.battleLog.length > 1000) {
            this.battleLog = this.battleLog.slice(-500);
        }
    }

    /**
     * 获取战斗日志
     */
    public getBattleLog(): IBattleLogEntry[] {
        return [...this.battleLog];
    }

    /**
     * 获取战斗统计
     */
    public getBattleStats(): {
        duration: number;
        totalActions: number;
        totalDamage: number;
        totalHealing: number;
        kills: number;
    } {
        const duration = this.endTime - this.startTime;
        const totalActions = this.battleLog.length;
        const totalDamage = this.battleLog.reduce((sum, log) => sum + (log.valueChange > 0 ? log.valueChange : 0), 0);
        const totalHealing = this.battleLog.reduce((sum, log) => sum + (log.valueChange < 0 ? -log.valueChange : 0), 0);
        const kills = this.battleLog.filter(log => log.actionType === 'kill').length;
        
        return {
            duration,
            totalActions,
            totalDamage,
            totalHealing,
            kills
        };
    }
} 